using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate;
using NHibernate.Criterion;

using Didsoft.DataAccess.Hibernate;
using Didsoft.DataAccess.Contracts;
using SIOGDE.AccesoDatos.Entidades;
using SIOGDE.AccesoDatos.Contratos;
using SIOGDE.AccesoDatos.Entidades.Lites;

namespace SIOGDE.AccesoDatos.Contexto
{
   public class UnidadMilitarAccesoDatos : DataAccessBasic<UnidadMilitar>, IUnidadMilitarAccesoDatos
   {
     public UnidadMilitarAccesoDatos()
     {
     }
     
     /// <summary>
     /// Devuelve una lista IList<UnidadMilitar> con todas las ocurrencias encontradas, en base a filtro.
     /// </summary>
     /// <param name="filtro"></param>
     /// <returns></returns>
     public IList<UnidadMilitar> BuscarPorFiltro(string filtro)
     {
             ICriteria criteria = Session.CreateCriteria(typeof(UnidadMilitar));
             criteria.Add(Expression.Like("Nombre","%"+filtro+"%")); 
             return criteria.List<UnidadMilitar>();
     }


     public IList<UnidadAsignadaInfo> GetDestinosSugerentes(int personaId, int gestionId)
     {
         string sql = @"declare @PersonaId int = :personaId,
		                        @GestionId int = :gestionId

                        --revisar los destinos anteriores

                        declare @ArmaId int,
                                @GradoId int,
                                @FechaEgreso datetime

                        select @armaId = ArmaId,
	                           @FechaEgreso = p.FechaEgreso 
						                        from PersonaArma pa 
						                        inner join Persona p on p.PersonaId = pa.PersonaId
						                        where p.PersonaId = @PersonaId and pa.EsActual = 1
                        select top 1 @GradoId = g.GradoId from HistorialAscenso ha 
						                        inner join Grado g on g.GradoId = ha.GradoId
						                        where ha.PersonaId = @PersonaId
						                        order by g.GradoId

                       declare @UnidadTable table (UnidadId int, Asignados int, Ocupados int, GuidRequerimiento varchar(500))
                        insert into @UnidadTable(UnidadId, Asignados, Ocupados, GuidRequerimiento) 
                        select um.UnidadMilitarId, rc.NumPersonas, COUNT(da.DestinoAsignadoId) Asignados, rc.Guid
                        from UnidadMilitar um 
                        inner join RequerimientoConfig rc on rc.UnidadMilitarId = um.UnidadMilitarId 
                        left join DestinoAsignado da on da.RequerimientoConfigId = rc.RequerimientoConfigId
                        where rc.GestionId = @gestionId 
	                        and rc.ArmaId = @ArmaId 
	                        and rc.GradoId = @GradoId 
	                        and @FechaEgreso between rc.PromocionDesde and rc.PromocionHasta
                        group by um.UnidadMilitarId, rc.NumPersonas, rc.Guid
                        having COUNT(da.DestinoAsignadoId) < rc.NumPersonas


                        select	GuidRequerimiento = ut.GuidRequerimiento,
		                        GuidUnidad = um.Guid,
                                um.Codigo, 
		                        um.Nombre, 
		                        um.Descripcion, 
		                        um.Direccion, 
		                        um.Email, 
		                        Latitud = cast(um.Latitud as float) ,
		                        Longitud = cast(um.Longitud as float), 
		                        ut.Asignados, 
		                        ut.Ocupados,
		                        Disponibles = ut.Asignados - ut.Ocupados 
                        from UnidadMilitar um
                        inner join @UnidadTable ut on ut.UnidadId = um.UnidadMilitarId
                        ";

         var query = Session.CreateSQLQuery(sql);
         query.SetInt32("personaId", personaId);
         query.SetInt32("gestionId", gestionId);
         return query.ListBeanTransformer<UnidadAsignadaInfo>();

     }


     public UnidadMilitar GetPorGuid(string guid)
     {
         string hql = "from UnidadMilitar um where um.Guid = :guid";
         var query = Session.CreateQuery(hql);
         query.SetAnsiString("guid", guid);
         return query.UniqueResult<UnidadMilitar>();
     }


     public IList<UnidadMilitar> GetUnidadesRaiz()
     {
         var query = Session.QueryOver<UnidadMilitar>().Where(p => p.UnidadPadre == null);
         return query.List<UnidadMilitar>().OrderBy(p => p.Nombre).ToList();
     }


     public IList<UnidadMilitar> GetDependientesDeUnidad(int unidadId)
     {
         var query = Session.QueryOver<UnidadMilitar>().Where(p => p.UnidadPadre.Id == unidadId);
         return query.List<UnidadMilitar>().OrderBy(p => p.Nombre).ToList();
     }
   }
}

